From: Owen W. Taylor Date: Fri, 12 Sep 2014 21:07:31 +0000 (-0400) Subject: background.js: fix updating a BackgroundSource on monitor changes X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~2132 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=0992bd41ed27d5f1243e9111a10e48d4631b5751;p=gnome-shell.git background.js: fix updating a BackgroundSource on monitor changes It was assumed that BackgroundSource objects were always destroyed on monitor changes because the BackgroundManager objects that hold references were destroyed, but sequencing of updating of different BackgroundManager objects meant that was not the case. Properly update any cached Background objects held by the BackgroundSource on a change to the monitor layout; in particular this means updating animations in case they are multi-resolution. --- diff --git a/js/ui/background.js b/js/ui/background.js index 00b9d6375..9ca9312ec 100644 --- a/js/ui/background.js +++ b/js/ui/background.js @@ -242,11 +242,7 @@ const Background = new Lang.Class({ destroy: function() { this._cancellable.cancel(); - - if (this._updateAnimationTimeoutId) { - GLib.source_remove (this._updateAnimationTimeoutId); - this._updateAnimationTimeoutId = 0; - } + this._removeAnimationTimeout(); let i; let keys = Object.keys(this._fileWatches); @@ -260,6 +256,13 @@ const Background = new Lang.Class({ this._settingsChangedSignalId = 0; }, + updateResolution: function() { + if (this._animation) { + this._removeAnimationTimeout(); + this._updateAnimation(); + } + }, + _setLoaded: function() { if (this.isLoaded) return; @@ -303,6 +306,13 @@ const Background = new Lang.Class({ this._fileWatches[filename] = signalId; }, + _removeAnimationTimeout: function() { + if (this._updateAnimationTimeoutId) { + GLib.source_remove(this._updateAnimationTimeoutId); + this._updateAnimationTimeoutId = 0; + } + }, + _updateAnimation: function() { this._updateAnimationTimeoutId = 0; @@ -477,6 +487,23 @@ const BackgroundSource = new Lang.Class({ this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE'); this._settings = new Gio.Settings({ schema_id: settingsSchema }); this._backgrounds = []; + + this._monitorsChangedId = global.screen.connect('monitors-changed', + Lang.bind(this, this._onMonitorsChanged)); + }, + + _onMonitorsChanged: function() { + for (let monitorIndex in this._backgrounds) { + let background = this._backgrounds[monitorIndex]; + + if (monitorIndex < this._layoutManager.monitors.length) { + background.updateResolution(); + } else { + background.disconnect(background._changedId); + background.destroy(); + delete this._backgrounds[monitorIndex]; + } + } }, getBackground: function(monitorIndex) { @@ -513,8 +540,8 @@ const BackgroundSource = new Lang.Class({ style: style }); - let changedId = background.connect('changed', Lang.bind(this, function() { - background.disconnect(changedId); + background._changedId = background.connect('changed', Lang.bind(this, function() { + background.disconnect(background._changedId); background.destroy(); delete this._backgrounds[monitorIndex]; })); @@ -526,8 +553,13 @@ const BackgroundSource = new Lang.Class({ }, destroy: function() { - for (let monitorIndex in this._backgrounds) - this._backgrounds[monitorIndex].destroy(); + global.screen.disconnect(this._monitorsChangedId); + + for (let monitorIndex in this._backgrounds) { + let background = this._backgrounds[monitorIndex]; + background.disconnect(background._changedId); + background.destroy(); + } this._backgrounds = null; }